package net.oschina.gitapp.widget;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;

import net.oschina.gitapp.bean.URLs;
import net.oschina.gitapp.common.StringUtils;
import net.oschina.gitapp.common.UIHelper;
import android.content.Context;
import android.graphics.Color;
import android.text.Editable;
import android.text.Html;
import android.text.Html.TagHandler;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

/**
 * 超链接文本控件
 * 
 * @author liux (http://my.oschina.net/liux)
 * @version 1.0
 * @created 2012-3-21
 */
public class LinkView extends TextView {
    private OnLinkClickListener mLinkClickListener = new LinkView.OnLinkClickListener() {
        @Override
        public void onLinkClick() {
            
        }
    };
    
    public LinkView(Context context) {
        super(context);
    }
    
    public LinkView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public LinkView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    public OnLinkClickListener getLinkClickListener() {
        return mLinkClickListener;
    }
    
    public void setLinkClickListener(OnLinkClickListener linkClickListener) {
        this.mLinkClickListener = linkClickListener;
    }
    
    public final static Pattern WECHAT_REG = Pattern
            .compile("(<{1}img[\\s]+class=\"wechat-emoji\"[\\s]+src=\"[^<]+\"[\\s]+alt=\"([^<\\s\"]+)\"[\\s]+[^<]*[>]{1})");
    
    private static String filterWechat(String linktxt) {
        System.out.println(linktxt);
        if (null == linktxt)
            return "";
        try {
            Matcher match = WECHAT_REG.matcher(linktxt);
            if (null == match)
                return linktxt;
            while (match.find()) {
                String target = match.group(1);
                String rp = match.group(2);
                linktxt = linktxt.replace(target, "[" + rp + "]");
            }
        }
        catch (Exception e) {
            return linktxt;
        }
        return linktxt;
    }
    
    public void setLinkText(String linktxt) {
        linktxt = filterWechat(linktxt);
        Spanned span = Html.fromHtml(linktxt);
        setText(span);
        setMovementMethod(LinkMovementMethod.getInstance());
        parseLinkText(span);
    }
    
    public void parseLinkText(Spanned spanhtml) {
        CharSequence text = getText();
        if (text instanceof Spannable) {
            int end = text.length();
            Spannable sp = (Spannable) getText();
            URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
            
            URLSpan[] htmlurls = spanhtml != null ? spanhtml.getSpans(0, end,
                    URLSpan.class) : new URLSpan[] {};
            
            if (urls.length == 0 && htmlurls.length == 0)
                return;
            
            SpannableStringBuilder style = new SpannableStringBuilder(text);
            // style.clearSpans();// 这里会清除之前所有的样式
            for (URLSpan url : urls) {
                if (!isNormalUrl(url)) {
                    style.removeSpan(url);// 只需要移除之前的URL样式，再重新设置
                    NoLinkSpan span = new NoLinkSpan(url.getURL());
                    style.setSpan(span, sp.getSpanStart(url),
                            sp.getSpanEnd(url),
                            Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                    continue;
                }
                style.removeSpan(url);// 只需要移除之前的URL样式，再重新设置
                MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
                style.setSpan(myURLSpan, sp.getSpanStart(url),
                        sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            for (URLSpan url : htmlurls) {
                style.removeSpan(url);// 只需要移除之前的URL样式，再重新设置
                MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
                style.setSpan(myURLSpan, spanhtml.getSpanStart(url),
                        spanhtml.getSpanEnd(url),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            setText(style);
        }
    }
    
    public void parseLinkText() {
        parseLinkText(null);
    }
    
    public class MyURLSpan extends ClickableSpan {
        private String mUrl;
        
        public MyURLSpan(String url) {
            mUrl = url;
        }
        
        @Override
        public void onClick(View widget) {
            mLinkClickListener.onLinkClick();
            /*
             * URLs urls = URLs.parseURL(mUrl); if (urls != null) {
             * UIHelper.showLinkRedirect(widget.getContext(), urls.getObjType(),
             * urls.getObjId(), urls.getObjKey()); } else {
             * UIHelper.openBrowser(widget.getContext(), mUrl); }
             */
        }
    }
    
    /**
     * 无响应的ClickableSpan
     * 
     * @author yeguozhong@yeah.net
     * 
     */
    public class NoLinkSpan extends ClickableSpan {
        private String text;
        
        public NoLinkSpan(String text) {
            super();
            this.text = text;
        }
        
        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(Color.BLACK);
            ds.setUnderlineText(false); // 去掉下划线
        }
        
        @Override
        public void onClick(View widget) {
            // doNothing...
        }
        
    }
    
    public interface OnLinkClickListener {
        void onLinkClick();
    }
    
    /**
     * 过滤掉一些不正常的链接
     * 
     * @param url
     * @return
     */
    public boolean isNormalUrl(URLSpan url) {
        String urlStr = url.getURL();
        if (urlStr.endsWith(".sh")) {
            return false;
        }
        return true;
    }
}
